﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Lottery.MediaData.Core {
    /// <summary>
    /// 过滤表数据在内存中的表示
    /// </summary>
    public class FTCellData {
        private List<List<string>> m_data = new List<List<string>>();

        public string this[int col, int row] {
            get {
                return m_data[row][col];
            }

            set {
                m_data[row][col] = value;
            }
        }

        public void AddRow(List<string> row) {
            var r = new List<string>(row);

            for (int i = 0; i < ColCount - row.Count; i++)
                r.Add(string.Empty);

            m_data.Add(r);
        }

        public int RowCount {
            get { return m_data.Count; }
        }

        public int ColCount {
            get { return 18; }
        }

        public void Clear() {
            m_data = new List<List<string>>();
        }

        public void AddFtCell(FTCellData ft) {
            int rowIndex = this.RowCount;
            for (int row = 0; row < ft.RowCount; row++) {
                rowIndex++;

                var r = new List<string>();
                r.Add(rowIndex.ToString());

                for (int col = 1; col < ft.ColCount; col++) {
                    r.Add(ft[col, row]);
                }

                this.AddRow(r);
            }
        }

        private int[] m_low;
        private int[] m_up;
        public int GetLow(int row) {
            return m_low[row];
        }

        public int GetUp(int row) {
            return m_up[row];
        }

        public void SetUpLow() {
            m_low = new int[this.RowCount];
            m_up = new int[this.RowCount];
            for (int row = 0; row < this.RowCount; row++) {
                var limits = this[15, row].Split('-');
                m_low[row] = Convert.ToInt32(limits[0].Trim());
                m_up[row] = Convert.ToInt32(limits[1].Trim());
            }
        }

        public int GetRowValidCount(int row) {
            int result = 0;
            for (int col = 1; col < 15; col++) {
                if (!string.IsNullOrEmpty(this[col, row]))
                    result++;
            }

            return result;
        }

        public FTCellData CreateFT() {
            var result = new FTCellData();
            this.SetUpLow();

            for (int row = 0; row < this.RowCount; row++) {
                var low = GetLow(row);
                var up = GetUp(row);
                if (low == 0 && up == GetRowValidCount(row)) {
                    // 忽略 0-N，其中N是一行中数据的场数之和
                    // 0-N 实际上不起过滤作用
                    continue;
                }

                var list = new List<string>();
                for (int col = 0; col < this.ColCount; col++) {
                    list.Add(this[col, row]);
                }
                result.AddRow(list);
            }

            result.SetUpLow();
            result.AdjustUpLow();
            result.SetFtFlags();

            return result;
        }

        private void AdjustUpLow() {
            // 例如
            // 一行的数据是 310,0,310,1,1,... 过滤是  3-5
            // 因为 有两个310
            // 所以过滤可以调整为 1-3 ,同时把数据中的310变成空

            for (int row = 0; row < this.RowCount; row++) {
                int tozCount = 0;
                for (int col = 1; col < 15; col++) {
                    if (this[col, row] == "310") {
                        tozCount++;
                        this[col, row] = string.Empty;
                    }
                }
                int low = m_low[row] - tozCount;
                if (low < 0) low = 0;
                int up = m_up[row] - tozCount;
                if (up < 0) up = 0;
                m_low[row] = low;
                m_up[row] = up;
            }
        }

        /// <summary>
        /// 判断限制是否是0-0
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public bool IsZeroToZero(int row) {
            return m_low[row] == 0 && m_up[row] == 0;
        }

        private List<long> m_ftFlags;
        
        public long GetFtFlags(int row) {
            return m_ftFlags[row];
        }

        private void SetFtFlags() {
            m_ftFlags = new List<long>();
            for (int row = 0; row < this.RowCount; row++) {
                var low = m_low[row];
                var up = m_up[row];

                var flag = 0L;
                for (int col = 1; col < 15; col++) {
                    var c = this[col, row];
                    if (string.IsNullOrEmpty(c)) continue;

                    foreach (var ch in c) {
                        flag |= FTHelper.CharToLong(ch) << (14 - col) * 3;
                    }
                }
                m_ftFlags.Add(flag);
            }
        }

    }
}
